package com.kr.weitao.util.rest.query;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.kr.weitao.exception.CommonException;
import com.kr.weitao.util.StringUtils;
import com.kr.weitao.util.rest.condition.Condition;
import com.kr.weitao.util.rest.condition.EColumnAuthority;
import com.kr.weitao.util.rest.condition.MysqlCondition;
import com.kr.weitao.util.rest.dataengine.DataDisposeEngine;
import com.kr.weitao.util.rest.datatrigger.DataACTrigger;
import com.kr.weitao.util.rest.datatrigger.DataBCTrigger;
import com.kr.weitao.util.rest.schema.Column;
import com.kr.weitao.util.rest.schema.Function;
import com.kr.weitao.util.rest.schema.FunctionManager;
import com.kr.weitao.util.spring.SpringUtils;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/** Created by paco on 2017/06/12. */
@Log4j2
@Component
@Scope("prototype")
public class ObjectCreateUtil {
  @Autowired
  @Qualifier("mySQLDataEngine")
  DataDisposeEngine de;

  @Autowired private FunctionManager tableManager;

  @Transactional
  public long execute(JSONObject param,EColumnAuthority ec) throws CommonException {
    List<Column> user_columns = null; //用户字段权限
    Function table = null; //数据表
    JSONObject master_tableinfo = null; //主表数据
    JSONArray items = null; //明细记录
    long masterId = 0; //主记录ID
    long user_id = 0; //用户ID

    //region 参数判断
    //region 1、系统参数判断
    if (param == null || param.isEmpty()) {
      log.error("param is null");
      throw new CommonException("-1", "参数不能为空");
    }

    //endregion

    //region 2、获取用户信息
    if (!param.containsKey("user_id")) {
      log.error("param not has user_id,param;" + param.toJSONString());
      throw new CommonException("-3", "缺少用户信息");
    }

    user_id = param.getLongValue("user_id");
    if (user_id == 0) {
      log.error("param user_id error,param;" + param.toJSONString());
      throw new CommonException("-3", "缺少用户信息");
    }
    //endregion

    //region 3、业务参数判断
    //region 1、判断主表信息是否完整
    if (!param.containsKey("function")) {
      log.error("data not has table key:" + param);
      throw new CommonException("-3", "请选择要操作的菜单");
    }

    String table_name = param.getString("function");
    if (StringUtils.isNull(table_name)) {
      log.error("data table is null:" + param);
      throw new CommonException("-3", "请选择要操作的菜单");
    }

    table = tableManager.getByName(table_name);
    if (table == null) {
      log.error("data table object is null:" + param);
      throw new CommonException("-3", "请选择要操作的菜单");
    }

    master_tableinfo = param.getJSONObject("master_object");
    if (master_tableinfo == null || master_tableinfo.isEmpty()) {
      log.error("master_object datainfo is null:" + param);
      throw new CommonException("-3", "请维护要增加的数据");
    }
    //endregion

    //region 2、判断明细数据是否完整
    JSONArray tempitems = param.getJSONArray("items");
    JSONObject tempiteminfo = null;
    if (tempitems != null && tempitems.size() > 0) {
      int ilength = tempitems.size();
      String tempforeignTable = null;
      String tempforeignColumn = null;
      JSONArray tempadd = null;

      for (int i = 0; i < ilength; i++) {
        tempiteminfo = tempitems.getJSONObject(i);
        if (tempiteminfo == null || tempiteminfo.isEmpty()) {
          continue;
        }
        tempforeignTable = tempiteminfo.getString("foreign_object_name");
        if (StringUtils.isNull(tempforeignTable)) {
          log.error("item index:" + i + " foreign_object_name is null,param:" + param);
          throw new CommonException("-3", "请维护要操作的关联表");
        }

        tempforeignColumn = tempiteminfo.getString("foreign_field");
        if (StringUtils.isNull(tempforeignColumn)) {
          log.error("item index:" + i + " foreign_field is null,param:" + param);
          throw new CommonException("-3", "请维护要操作的关联字段");
        }

        tempadd = tempiteminfo.getJSONArray("add_list");
        if (tempadd == null || tempadd.size() <= 0) {
          log.error("item index:" + i + " add_list is null,param:" + param);
          throw new CommonException("-3", "请维护要新增的明细表数据");
        }

        items.add(tempiteminfo);
      }
    }
    //endregion
    //endregion

    //region 4、获取REDIS中的用户字段权限
    //user_columns= JSON.parseArray(user_cache.toJSONString(),Sys_Column.class);
    user_columns = table.getUserColumns(user_id, ec);
    if (user_columns == null || user_columns.size() <= 0) {
      log.error("redis user_columns is null,param;" + param.toJSONString());
      throw new CommonException("-3", "用户权限不足");
    }

    //求出接口传入的查询字段与用户权限字段的交集

    //endregion
    //endregion

    //region BC处理
    String bcclassname = table.getDataBCClassName();
//    log.debug("------ObjectCreateUtil:"+table.getIsBc()+","+bcclassname);
    if (table.getIsBc() && StringUtils.isNotNull(bcclassname)) {
      DataBCTrigger dataBCTrigger = null;
      try {
        Class clazz=Class.forName(bcclassname);
        if(clazz.isAnnotationPresent(Component.class)){
          dataBCTrigger = (DataBCTrigger)SpringUtils.getBean(clazz);
        }else{
          dataBCTrigger = (DataBCTrigger) clazz.newInstance();
        }
      } catch (Exception e) {
        log.error("get DataBCTrigger instance error:" + e.getLocalizedMessage(), e);
        throw new CommonException("-80", "BM 配置有误");
      }

      dataBCTrigger.execute(table, param);
    }
    //endregion

    //region 主表数据处理
    JSONObject createParam = new JSONObject();
    createParam.put("master_object", param.getJSONObject("master_object"));
    createParam.put("user_id", param.getLongValue("user_id"));
    Condition mysqlConditeion = MysqlCondition.getInstance(table);
    masterId =
        de.insert(
            mysqlConditeion.getCreateSql(createParam, user_columns),
            mysqlConditeion.getCreateDataParam());
    param.put(table.getPK().getDb_name(), masterId);
    //endregion

    //region 处理明细数据
    if (items != null && items.size() > 0) {
      Function tempfortable = null; //外键关联表
      Column tempforcolumn = null; //外键关联字段
      JSONArray tempadd = null; //要新增的明细数据

      String tempforeignTableName = null; //外键关联表名称
      String tempforeignColumnName = null; //外键关联字段名称

      int ilength = items.size();

      for (int i = 0; i < ilength; i++) {
        tempiteminfo = items.getJSONObject(i);
        if (tempiteminfo == null || tempiteminfo.isEmpty()) {
          continue;
        }

        //region 判断明细参数
        tempforeignTableName = tempiteminfo.getString("foreign_object_name");
        if (StringUtils.isNull(tempforeignTableName)) {
          log.error("item index:" + i + " foreign_object_name is null,param:" + param);
          throw new CommonException("-90", "请维护要新增的明细表数据");
        }
        tempfortable = tableManager.getByName(tempforeignTableName);
        if (tempfortable == null) {
          log.error("item index:" + i + " not find foreign table by name:" + tempforeignTableName);
          throw new CommonException("-90", "请正确维护要操作的关联表");
        }

        tempforeignColumnName = tempiteminfo.getString("foreign_field");
        if (StringUtils.isNull(tempforeignColumnName)) {
          log.error("item index:" + i + " foreign_field is null,param:" + param);
          throw new CommonException("-90", "请维护要操作的关联字段");
        }
        tempforcolumn = table.getColumnByDBName(tempforeignColumnName);
        if (tempforcolumn == null) {
          log.error(
              "item index:" + i + " not find foreign column by name:" + tempforeignColumnName);
          throw new CommonException("-90", "请正确维护要操作的关联字段");
        }

        tempadd = tempiteminfo.getJSONArray("add_list");
        if (tempadd == null || tempadd.size() <= 0) {
          log.error("item index:" + i + " add_list is null,param:" + param);
          throw new CommonException("-90", "请维护要新增的明细表（" + tempfortable.getShowName() + "）数据");
        }
        //endregion

        //region 外理明细数据
        int alength = tempadd.size();
        JSONObject tempAddInfo = null;
        for (int j = 0; j < alength; j++) {
          tempAddInfo = tempadd.getJSONObject(j);
          if (tempAddInfo == null || tempAddInfo.isEmpty()) {
            log.error("-80", "add foreign table:" + tempfortable.getShowName() + " data is null");
            throw new CommonException("-90", "请维护要新增的明细表（" + tempfortable.getShowName() + "）数据");
          }

          JSONObject createjo = new JSONObject();
          JSONObject tempForeignData = tempAddInfo.getJSONObject("master_object");
          tempForeignData.put(tempforcolumn.getDb_name(), masterId);
          createjo.put("function", tempforeignTableName);
          createjo.put("master_object", tempForeignData);
          createjo.put("items", tempAddInfo.getJSONArray("items"));
          createjo.put("user_id", user_id);

          //创建数据
          SpringUtils.getBean(ObjectCreateUtil.class).execute(createjo,EColumnAuthority.itemdate);
        }
        //endregion
      }
    }
    //endregion

    //region AC处理
    String acclassname = table.getDataACClassName();
    if (table.getIsAc() && StringUtils.isNotNull(acclassname)) {
      DataACTrigger dataACTrigger = null;
      try {
        Class clazz=Class.forName(acclassname);
        if(clazz.isAnnotationPresent(Component.class)){
          dataACTrigger = (DataACTrigger)SpringUtils.getBean(clazz);
        }else{
          dataACTrigger = (DataACTrigger) clazz.newInstance();
        }
      } catch (Exception e) {
        log.error("get DataBCTrigger instance error:" + e.getLocalizedMessage(), e);
        throw new CommonException("-80", "BM 配置有误");
      }

      dataACTrigger.execute(table, param);
    }
    //endregion

    return masterId;
  }
}
